package com.guge.sports.toolPackage.base;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guge.sports.toolPackage.interfaces.BaseServiceInterface;
import com.guge.sports.toolPackage.interfaces.SelectListQueryWrapper;
import com.guge.sports.toolPackage.interfaces.SelectPageQueryWrapper;
import com.guge.sports.toolPackage.utils.ApplicationContextUtils;
import com.guge.sports.toolPackage.utils.MyPager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import java.lang.reflect.Field;
import java.util.List;

//implements ApplicationListener<ContextRefreshedEvent>
public class BaseService<T extends Model> implements InitializingBean {

    protected BaseMapper<T> mapper;

    protected Class<T> entityCls;

    private void initMapper() {
        BaseMapper baseMapper = ApplicationContextUtils.getMapperByGenericType(getClass());
        //System.out.println("baseMapper="+baseMapper);

        if (baseMapper != null) {
            //System.out.println("赋值baseMapper" + baseMapper);
            this.mapper = baseMapper;
        }
        Class entityCls = ApplicationContextUtils.getEntityCls();
        if (entityCls != null) {
            this.entityCls = entityCls;
        }
    }


    public List<T> selectAll() {
        return mapper.selectList(null);
    }

    public List<T> selectList(T entity) {
        return entity.selectList(getListWrapper(entity));
    }


    public T selectOne(T entity) {
        return (T) entity.selectOne(getCommonWrapper(entity));
    }


    public T selectById(T entity) {
        return (T) entity.selectById();
    }


   /* //批量查询
    public List<T> selectBatchIds(List<Integer> ids) {
        return mapper.selectBatchIds(ids);
    }*/

    public Integer selectAllCount() {
        return mapper.selectCount(null);
    }

    public Integer selectCount(T entity) {
        return entity.selectCount(getCommonWrapper(entity));
    }


    public boolean deleteById(T entity) {
        return entity.deleteById();
    }

    //批量删除
    public boolean deleteBatchIds(List<Integer> ids) {
        return mapper.deleteBatchIds(ids) == ids.size();
    }


    public boolean delete(T entity) {
        return entity.delete(getCommonWrapper(entity));
    }


    //通过id修改
    public boolean updateById(T entity) {
        return entity.updateById();
    }

    //新增
    public boolean insert(T entity) {
        return entity.insert();
    }


    public MyPager<T> selectPage(MyPager<T> myPager, T entity) {
        //System.out.println(entity);
        Page<T> page = new Page<>(myPager.getCurrentPage(), myPager.getPageCount());
        Wrapper wrapper = getPageWrapper(entity);
        IPage iPage = mapper.selectPage(page, wrapper);
        //System.out.println("iPage=="+iPage);
        myPager.warp2MyPager(iPage);
        //System.out.println(myPager);
        return myPager;
    }


    /**
     * @param
     * @param t
     * @return
     */
    private Wrapper getListWrapper(T t) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        handleListWrapper(t, queryWrapper);
        if (this instanceof SelectListQueryWrapper) {
            SelectListQueryWrapper wrapper = (SelectListQueryWrapper) this;
            queryWrapper = wrapper.handleSelectListQuery(t, queryWrapper);
        }
        System.out.println(queryWrapper);
        return queryWrapper;
    }


    private Wrapper getCommonWrapper(T t) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        handleListWrapper(t, queryWrapper);
        return queryWrapper;
    }


    private void handleListWrapper(T t, QueryWrapper<T> queryWrapper) {
        try {
            Field[] declaredFields = entityCls.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                Object o = declaredField.get(t);
                if (o != null && !"".equals(o) && !"serialVersionUID".equals(declaredField.getName())) {
                    String name = getColumnName(declaredField);
                    queryWrapper.eq(name, o);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * @param
     * @param t
     * @return
     */
    private Wrapper getPageWrapper(T t) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        handlePageWrapper(t, queryWrapper);
        if (this instanceof SelectPageQueryWrapper) {
            SelectPageQueryWrapper wrapper = (SelectPageQueryWrapper) this;
            queryWrapper = wrapper.handleSelectPageQuery(t, queryWrapper);
        }
        return queryWrapper;
    }

    private void handlePageWrapper(T t, QueryWrapper<T> queryWrapper) {
        try {
            Field[] declaredFields = entityCls.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                Object o = declaredField.get(t);
                if (o == null) {
                    continue;
                }
                if (o instanceof String && !"".equals(o) && !"serialVersionUID".equals(declaredField.getName())) {
                    String name = getColumnName(declaredField);
                    queryWrapper.like(name, o);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private String getColumnName(Field field) {
        String fieldName = field.getName();
        if (field.isAnnotationPresent(TableField.class)) {
            fieldName = field.getAnnotation(TableField.class).value();
        }
        return fieldName;
    }


    /**
     * 将驼峰转为下划线
     *
     * @return
     */
    private String convertCamel2Under(String fieldName) {
        //c = c.replaceAll("([a-z])([A-Z])", "$1"+separator+"$2").toLowerCase();
        return fieldName.replaceAll("([A-Z])", "_" + "$1").toLowerCase();
    }


   /* @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

        *//*if (event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")) {
            System.out.println("spring初始化完成。。。");
            initMapper();
        }*//*
        //System.out.println("spring初始化完成。。。");
        initMapper();
    }
*/

    @Override
    public void afterPropertiesSet() throws Exception {
        //System.out.println("属性初始化-----mapper-------");
        initMapper();
    }
}
